Type.registerNamespace("BM");

// Restriction object

BM.Restriction = function(leafItem, additionNode) {
    BM.Restriction.initializeBase(this, [leafItem, additionNode]);
}

BM.Restriction.prototype = {

    getRestrictionType: function() {
        ///	<summary>
        ///	returns constraint type (maximal length, minimal length, etc.)
        ///	</summary>
        ///	<returns type="String" />  
        return this.additionNode.getAttribute('type');
    },

    getRestriction: function() {
        ///	<summary>
        ///	returns the value to which the constraint is restricted
        ///	</summary>
        ///	<returns type="String" /> 
        return this.additionNode.innerHTML;
    },

    isMet: function() {
        switch (this.getRestrictionType()) {
            case 'Length':
                return BM.Restriction.isExactLength(this.getValue(), this.getRestriction());
            case 'MaxLength':
                return !BM.Restriction.isLongerThan(this.getValue(), this.getRestriction());
            case 'MinLength':
                return !BM.Restriction.isShorterThan(this.getValue(), this.getRestriction());
            case 'MinInclusive':
                return !BM.Restriction.isSmallerThan(this.getValue(), this.getRestriction());
            case 'MaxInclusive':
                return !BM.Restriction.isLargerThan(this.getValue(), this.getRestriction());
            case 'MinExclusive':
                return BM.Restriction.isLargerThan(this.getValue(), this.getRestriction());
            case 'MaxExclusive':
                return BM.Restriction.isSmallerThan(this.getValue(), this.getRestriction());
            case 'Pattern':
                return BM.Restriction.matchRegExp(this.getValue(), this.getRestriction());
            case 'TotalDigits':
                return BM.Restriction.hasTotalDigits(this.getValue(), this.getRestriction());
            case 'FractionDigits':
                return BM.Restriction.hasFractionDigits(this.getValue(), this.getRestriction());
        }
        return true;
    },

    getDefaultErrorText: function() {
        return BM.RestrictionErrors[this.getRestrictionType()] + " " + this.getRestriction();
    },

    addCurrent: function(parent, value) {
        BM.NodeBuilder.createSpan(parent, 'Current', '(' + value + ')');
    },

    appendDescription: function(node) {
        if (this.getInfoText() != null) {
            BM.Restriction.callBaseMethod(this, 'appendDescription', [node]);
            return;
        }

        this.appendInferredDescription(node);
    },

    appendInferredDescription: function(node) {
        var ct = BM.NodeBuilder.createDiv(node, "Constraint");
        BM.NodeBuilder.createSpan(ct, 'Type', BM.RestrictionTypes[this.getRestrictionType()] + ':');
        BM.NodeBuilder.createSpan(ct, 'Value', this.getRestriction());

        if (this.getRestrictionType().indexOf('TotalDigits') != -1) {
            this.addCurrent(ct, BM.Restriction.getTotalDigits(this.getValue()));
        }
        else if (this.getRestrictionType().indexOf('FractionDigits') != -1) {
            this.addCurrent(ct, BM.Restriction.getFractionDigits(this.getValue()));
        }
        else if (this.getRestrictionType().indexOf('Length') != -1) {
            this.addCurrent(ct, this.getValue().length);
        }
        else if (this.getRestrictionType().indexOf('Inclusive') != -1 || this.getRestrictionType().indexOf('Exclusive') != -1) {
            this.addCurrent(ct, parseFloat(this.getValue()));
        }
    }
}

BM.Addition['Restriction'] = BM.Restriction;
BM.Restriction.registerClass("BM.Restriction", BM.Constraint);

/* length, size, regex tests */
BM.Restriction.isLargerThan = function(fieldValue, number) {
    return (parseFloat(fieldValue) > parseFloat(number));
}

BM.Restriction.isSmallerThan = function(fieldValue, number) {
    return (parseFloat(fieldValue) < parseFloat(number));
}

BM.Restriction.isShorterThan = function(fieldValue, number) {
    return (parseInt(fieldValue.length) < parseInt(number));
}

BM.Restriction.isLongerThan = function(fieldValue, number) {
    return (parseInt(fieldValue.length) > parseInt(number));
}

BM.Restriction.isExactLength = function(fieldValue, number) {
    return (parseInt(fieldValue.length) == parseInt(number));
}

BM.Restriction.matchRegExp = function(fieldValue, exp) {
    exp = new RegExp('^' + exp + '$');
    try {
        return fieldValue.match(exp);
    } catch (err) {
        alert('Invalid regular expression:' + exp);
        return true;
    }
}

BM.Restriction.getTotalDigits = function(fieldValue) {
    var digits = new String(parseFloat(fieldValue)).length;
    if (fieldValue.lastIndexOf('.') != -1) {
        digits--;
    }
    return parseInt(digits);
}

BM.Restriction.getFractionDigits = function(fieldValue) {
    fieldValue = new String(parseFloat(fieldValue));
    var dot = fieldValue.lastIndexOf('.');
    var digits = 0;
    if (dot != -1) {
        digits = fieldValue.length - dot - 1;
    }
    return parseInt(digits);
}

BM.Restriction.hasTotalDigits = function(fieldValue, value) {
    return BM.Restriction.getTotalDigits(fieldValue) <= value;
}

BM.Restriction.hasFractionDigits = function(fieldValue, value) {
    return BM.Restriction.getFractionDigits(fieldValue) <= value;
}


